<?php
require_once "Zend/Filter/Interface.php";

/**
 * Фильтр для преобразования плоского массива в древовидный
 * 
 * @category Phorm
 * @package Filter
 * @name /Phorm/Filter/Tree.php
 * @copyright phorm.ru
 * @since 01.03.2012
 * @author vladimir@kachalov.net
 */

class Phorm_Filter_Tree implements Zend_Filter_Interface {
		
	/**
	 * Возвращает массив в виде дерева (многомерной иерархии)
	 * Позаимствовано с http://stackoverflow.com/questions/841014/nested-sets-php-array-and-transformation
	 *
	 * @param array  $array Плоский массив
	 * @param string $depth Ключ массива в котором лежит номер уровня
	 * @param string $children Ключ массива в котором будут лежать дети
	 * @return array
	 */
		
	public function filter($array = array(), $depth = 'clevel', $children = 'children') {
		
		// Trees mapped
		$trees = array();
		$l = 0;

        if (count($array) > 0) {
        	// Node Stack. Used to help building the hierarchy
        	$stack = array();
        	
        	foreach ($array as $node) {
        		
        		$item = $node;
        		//$item[$children] = array();
        		
        		// Number of stack items
        		$l = count($stack);
        		
        		// Check if we're dealing with different levels
        		while($l > 0 && $stack[$l - 1][$depth] >= $item[$depth]) {
        			array_pop($stack);
        			$l--;
        		}
        		
        		// Stack is empty (we are inspecting the root)
        		if ($l == 0) {
        			// Assigning the root node
        			$i = count($trees);
        			$trees[$i] = $item;
        			$stack[] = & $trees[$i];
        		} else {
        			// Add node to parent
        			$i = key_exists($children,$stack[$l - 1]) ? count($stack[$l - 1][$children]) : 0;
        			$stack[$l - 1][$children][$i] = $item;
        			$stack[] = & $stack[$l - 1][$children][$i];
        		}
        	}
		}
		
		return $trees;
	}
		
		
}

